package my.mark.mybaibaoxiang.juc.biji01.util;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * Unsafe类使Java拥有了像C语言的指针一样操作内存空间的能力，
 * 一旦能够直接操作内存，这也就意味着（1）不受jvm管理，也就意味着无法被GC，需要我们手动GC，稍有不慎就会出现内存泄漏。
 * （2）Unsafe的不少方法中必须提供原始地址(内存地址)和被替换对象的地址，偏移量要自己计算，
 * 一旦出现问题就是JVM崩溃级别的异常，会导致整个JVM实例崩溃，表现为应用程序直接crash掉。
 * （3）直接操作内存，也意味着其速度更快，在高并发的条件之下能够很好地提高效率。
 */
public class UnsafeInstance {

    public static Unsafe reflectGetUnsafe() {
        try {
            //Unsafe类中定义了许多可以直接越过虚拟机操作底层的方法。
            /** 魔术类
             * Unsafe的初始化方法主要是通过getUnsafe方法的单例模式实现的，调用JVM本地方法registerNatives()和sun.reflect.Reflection，
             * 通过Reflection.getCallerClass()判断当前调用的类是否是主类加载器(BootStrap classLoader)加载的，否则的话抛出一个SecurityException。
             * 这也证明了一个问题，那就是只有由主类加载器(BootStrap classLoader)加载的类才能调用这个类中的方法。
             * 我们自己开发的类是不让直接调用的，要调用只能通过反射。
             */
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            return (Unsafe) field.get(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
